/*
 * @(#)DocAuth.java 1.00 02 Ago 2007
 *
 * Copyright (c) 2005-2007 Soluciones Info Móviles S.A.C.
 * Av. Javier Prado Oeste 203 - Piso 13, Lima 27, Perú.
 * Todos los derechos reservados.
 */

package sim.auth;

import sim.framework.*;
import sim.framework.io.*;
import sim.utils.Utils;

/**
 * Documento que almacena la información de autenticación
 *
 * @author      Omar Quintana
 * @since       1.0
 */
public final class DocAuth extends Document implements FileGets {
    

    private byte[] m_Login = null; 	// bytes de autenticación
    private boolean m_Hit = false;
    private String m_UsrPassword;
    private boolean m_Authenticated = false;
    
    /**
     * Inicializa el documento.
     *
     * @param   s    simlet, la aplicación.
     */
    public DocAuth(Simlet s) {
        super(s);
    }
    
    /**
     * Carga los datos de un archivo determinado.
     *
     * @return          <code>true</code> si se pudo cargar el archivo
     *                  satisfactoriamente,
     *                  <code>false</code> en caso no se pueda abrir.
     * @see             sim.framework.io.File#read()
     */
    public boolean load() {
	//#ifdef DEBUG_DOCAUTH
	//# System.out.println("DocAuth::load() ENTERED");
	//#endif
        FileStream file = null;
        file = (FileStream) file.create(super.m_Simlet,
					FileNames.FILE_AUTH, File.MODE_READ);
        if (file != null) {
            m_Hit = false;
            file.gets(this);
            file.close();
        }
	//#ifdef DEBUG_DOCAUTH
	//# System.out.println("DocAuth::load() EXITING");
	//#endif
        return (m_Login != null);
    }

    public boolean fileGetsLine(final byte[] line, int size, int crlf) {
        // Si encontramos una linea con más de un caracter ...
	if (size - crlf > 0) {
	    // ... ese debe ser la cadena de login.
	    setLogin(line, 0, size - crlf);
	    // Si retorno falso nos aseguramos leer una linea.
	    return false;
	}
	return true;
    }
    
    /**
     * Almacena la información de autenticación.
     *
     * @return          <code>true</code> si se pudo guardar la data
     *                  <code>false</code> en caso no se pueda guardar.
     * @see             sim.framework.io.File#write()
     */
    public boolean save() {
	boolean ret = true;
        FileStream file = null;
	if (m_Login != null) {
	    ret = false;
	    file = (FileStream)file.create(super.m_Simlet,
					   FileNames.FILE_AUTH, 
					   file.MODE_WRITE);
	    if (file != null) {
		if (file.puts(m_Login)) {
		    ret = true;
		}
		file.close();
	    }
	}
	return ret;
    }

    public void setLogin(byte[] line, int start, int count){
	if (count > 0) {
	    m_Login = new byte[count];
	    // Paranoia
	    if (m_Login != null) {
		Utils.memcpy(m_Login, 0, line, start, count);
	    }
	}
    }
    
    public final byte[] getLogin() {
	return m_Login;
    }
        
    public void setPassword(final String password) {
	m_UsrPassword = password;
    }
    
    /**
     * Recupera el texto que representa el password en la
     * cadena de autenticación. Se considera como password, al
     * Ãºltimo campo de esta cadena.
     *
     * @return      una cadena que contiene el password
     */
    private String getPassword() {
	String password = null;
	int i = 0;
	if (m_Login != null) {
	    i = m_Login.length - 1;
	    while (i >= 0) {
		if (Utils.memncmp(m_Login, i, Utils.TOKEN, Utils.TOKEN_PIPE, 1) == 0) {
		    i++;
		    break;
		}
		i--;
	    }
	    password = new String(m_Login, i, m_Login.length - i);
	}
        return password;
    }
        
    /**
     * Retorna un flag que indica si el usuario se autenticó.
     *
     * @return  <code>true</code> si está autenticado,
     *          <code>false</code> en caso contrario.
     */    
    public boolean isAuthenticated() {
	String sysPassword;
	sysPassword = getPassword();
	if ((sysPassword != null) && (m_UsrPassword != null)) {
	    return (sysPassword.compareTo(m_UsrPassword) == 0);
	}
	return false;
    }

    /** 
     * Borra los archivo relacionados con la autenticación del usuario.
     * 
     */
    public static void delete() {
	File.delete(FileNames.FILE_AUTH);
    }
}
